//
//  CJBasePanCardCollectionViewFlowLayout.swift
//  TSListDemo
//
//  Created by qian on 2020/11/6.
//  Copyright © 2020 dvlproad. All rights reserved.
//
//  可拖动(不是滑动)的卡片collectionView

import UIKit

class CJBasePanCardCollectionViewFlowLayout: UICollectionViewFlowLayout {
    // MARK: - Init
    private(set) var leftRightPadding : CGFloat = 0
    private(set) var topPadding : CGFloat = 0
    private(set) var bottomPadding : CGFloat = 0
    /// 初始化layout：需要这些参数的原因是：因为cell要左滑、右滑，所以cell与collectionView是有间距的，才能保证左右滑动倾斜时候，视图能够显示出来
    /// - Parameters:
    ///   - leftRightPadding: 与视图的左和右边距
    ///   - topPadding: 与视图的上边距
    ///   - bottomPadding: 与视图的下半句
    init(leftRightPadding:CGFloat, topPadding:CGFloat, bottomPadding:CGFloat) {
        super.init();
        self.leftRightPadding = leftRightPadding
        self.topPadding = topPadding
        self.bottomPadding = bottomPadding
 
        self.collectionView?.decelerationRate = UIScrollView.DecelerationRate.fast
        self.collectionView?.isPagingEnabled = true
        self.scrollDirection = .vertical
        
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - 当前显示/滚动到第几个cell
    private(set) var curShowingIndex: NSInteger = 0      // 当前显示在屏幕中间的cell的index
    func updateLayoutCurShowingIndex(currShowingIndex: NSInteger) -> Void {
        self.curShowingIndex = currShowingIndex
    }
    
    
    // MARK: - 布局
    private var layoutAttributesArray: [UICollectionViewLayoutAttributes] = []
    override func prepare() {
        super.prepare()
        var array : [UICollectionViewLayoutAttributes] = []
        
        let itemCount = self.collectionView?.numberOfItems(inSection: 0)
        for i in 0 ..< itemCount! {
            let indexPath = IndexPath(item: i, section: 0)
            let attribute = UICollectionViewLayoutAttributes(forCellWith: indexPath)
            
            // 计算 frame(根据当前显示/滚动到的curShowingIndex，与移动的百分比无关)
            attribute.frame = self.frame(index: i, curShowingIndex: curShowingIndex)
            // 计算 scale（根据移动的百分比）
            let scale: CGFloat = self.getCellScale(index: i, curShowingIndex: curShowingIndex, offset: .zero, movePercent: 0)
            let transform: CGAffineTransform = CGAffineTransform(scaleX: scale, y: scale)
            attribute.transform = transform
            
            attribute.zIndex = 10000 - indexPath.row
            array.append(attribute)
        }
        self.layoutAttributesArray = array
    }
    
    
    func frame(index: NSInteger, curShowingIndex: NSInteger) -> CGRect {
        // 计算 frame(根据当前显示/滚动到的curShowingIndex，与移动的百分比无关)
        let collectionViewWidth = self.collectionView!.bounds.width
        let collectionViewHeight = self.collectionView!.bounds.height

        let cellWidth: CGFloat = collectionViewWidth - 2*self.leftRightPadding
        let cellHeight: CGFloat = collectionViewHeight - self.topPadding - self.bottomPadding
        
        var cellCenterX = collectionViewWidth / 2.0
        if index < curShowingIndex {
            cellCenterX = -collectionViewWidth / 2.0
        }
        let cellX: CGFloat = cellCenterX - cellWidth/2
        
        let cellY: CGFloat = self.topPadding
        
        let frame: CGRect = CGRect.init(x: cellX, y: cellY, width: cellWidth, height: cellHeight)
        return frame
    }
    

    override var collectionViewContentSize: CGSize {
        let collectionViewWidth = self.collectionView!.bounds.width
        let collectionViewHeight = self.collectionView!.bounds.height
        return CGSize(width: collectionViewWidth, height: collectionViewHeight)
    }
    
    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        return self.layoutAttributesArray[indexPath.row]
    }
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        return self.layoutAttributesArray
    }
    
    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        return true
    }
    
    
    // MARK: - Getter
    func getCellScale(index: NSInteger, curShowingIndex: NSInteger,  offset: CGPoint = .zero, movePercent:CGFloat = 0) -> CGFloat {
        var scale : CGFloat = 1.0
        
        if index < curShowingIndex {
            scale = 1.0
        } else if index <= curShowingIndex+2 {
            let indexAfterShow: NSInteger = index-curShowingIndex    // 从显示的位置开始数，要计算的这个cell的索引是多少
            scale = 1.0 - CGFloat(indexAfterShow) * 0.1
        } else {
            scale = 0.8
        }
        
        let lastScale: CGFloat = self.__offsetScale(scale: scale, offset: offset)
        
        return lastScale
    }
    
    /// 移动offset时候的的应该变成的scale
    func __offsetScale(scale: CGFloat, offset: CGPoint = .zero) -> CGFloat {
        let maxOffset = min(max(abs(offset.x), abs(offset.y)), 100) //maxOffset最大只可能为100
        let changeScaleValue = maxOffset / 1000
        
        var lastScale: CGFloat = scale + changeScaleValue   // 拖动的时候其他卡片cell变大
        lastScale = min(lastScale, 1.0)                     // 拖动的时候其他卡片cell变大,但不能超过第一张的大小
        
        //debugPrint("itemIndex=\(itemIndex), maxOffset=\(maxOffset), lastScale = \(lastScale)")
        
        return lastScale
    }
    
    
    
    // MARK: - 吸附
    /// 吸附到固定的位置
    override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
        print("offset:\(proposedContentOffset)")
        
        return proposedContentOffset
    }
}
